﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

#endregion
using Thinxoft.HttpLib; 
using System.IO;
using System.Xml;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Runtime.Remoting;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Collections.Specialized;

namespace HTTPReqMan
{
    public class XFileCompiler
    {


        static bool checking = true;

       

        static string TabSpace(int spaces)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < spaces; i++)
            {
                sb.Append("\t");
            }
            return sb.ToString();
        }

        public static void Run(HttpResource resource)
        {

            Parser parser = new Parser(resource);

            StringBuilder namespc = new StringBuilder();

            if (parser.Directives != null && parser.Directives.Namespaces != null)
            {
                //add namespaces from files if declared in directives
                
                foreach (string str in parser.Directives.Namespaces)
                {
                    if (str != "System" && str != "System.Text" && str != "System.Xml" && str != "System.Collections" && str != "System.Collection.Generic")
                    {
                        namespc.AppendFormat("using {0};\n", str);
                    }
                }
      
            }

            string code = string.Format(Properties.Resources.XmlPageSample, resource.FileNameWithoutExtension, parser.CodeListing,namespc.ToString());

            if (Compile(code, "xfiles/" + resource.FileNameWithoutExtension + ".dll", parser))
            {
                resource.Compiled = true;
            }

        }

        public static void Run(HttpResource resource, bool uncheck)
        {

            Parser parser = new Parser(resource);
            StringBuilder namespc = new StringBuilder();

            //add namespaces from files if declared in directives
            if (parser.Directives != null && parser.Directives.Namespaces != null)
            {                
                
                foreach (string str in parser.Directives.Namespaces)
                {
                    if (str != "System" && str != "System.Text" && str != "System.Xml" && str != "System.Collection" && str != "Syste,.Collection.Generic")
                    {
                        namespc.AppendFormat("using {0}; ", str);
                    }
                }
                
            }

            string code = string.Format(Properties.Resources.XmlPageSample, resource.FileNameWithoutExtension, parser.CodeListing, namespc.ToString());
            if (CompileUnChecked(code, "xfiles/" + resource.FileNameWithoutExtension + ".dll", parser))
            {
                resource.Compiled = true;
            }

            
            

        }

        static bool CompileUnChecked(string code, string tempAssembly, Parser parser)
        {
            if (File.Exists(tempAssembly))
            {
                File.Delete(tempAssembly);
            }

            CSharpCodeProvider compiler = new CSharpCodeProvider();
            CompilerParameters parameters = new CompilerParameters();
            parameters.GenerateExecutable = false;
            parameters.OutputAssembly = tempAssembly;

            StringBuilder errorResponse = new StringBuilder();

            //add code
            string[] text = new string[1];
            text[0] = code;

            //add assemblies
            List<string> assemblies = null;
            if (parser.Directives != null && parser.Directives.Assemblies != null)
            {
                assemblies = parser.Directives.Assemblies;
                assemblies.AddRange(new string[] { "System.Xml.dll", "System.dll", "mscorlib.dll", "Thinxoft.HttpLib.XFiles.dll" });
            }
            else
            {
                assemblies = new List<string>(new string[] { "System.Xml.dll", "System.dll", "mscorlib.dll", "Thinxoft.HttpLib.XFiles.dll" });
            }

            string[] asmDlls = assemblies.ToArray();
            parameters.ReferencedAssemblies.AddRange(asmDlls);



            CompilerResults results = compiler.CompileAssemblyFromSource(parameters, text);

            if (results.Errors.Count > 0)
            {
                errorResponse.Append("<b>The Specified file contained syntax errors</b><hr>");
                foreach (CompilerError err in results.Errors)
                {
                    errorResponse.AppendFormat("Error({2}) L({3})[Line{1},Column{4}]: {0}<br>", err.ErrorText, err.Line, err.ErrorNumber, err.IsWarning.ToString(), err.Column);
                }
                return false;
            }
            File.SetAttributes(tempAssembly, FileAttributes.Hidden);  //hides the file

            return true;
        }


        static bool Compile(string code, string tempAssembly, Parser parser)
        {

            if (File.Exists(tempAssembly))
            {

                return true;
            }
            else
            {
                CSharpCodeProvider compiler = new CSharpCodeProvider();
                CompilerParameters parameters = new CompilerParameters();
                parameters.GenerateExecutable = false;
                parameters.OutputAssembly = tempAssembly;

                StringBuilder errorResponse = new StringBuilder();

                //add code
                string[] text = new string[1];
                text[0] = code;

                //add assemblies
                List<string> assemblies = null;
                if (parser.Directives != null && parser.Directives.Assemblies != null)
                {
                    assemblies = parser.Directives.Assemblies;
                    assemblies.AddRange(new string[] { "System.Xml.dll", "System.dll", "mscorlib.dll", "Thinxoft.HttpLib.XFiles.dll" });
                }
                else
                {
                    assemblies = new List<string>(new string[] { "System.Xml.dll", "System.dll", "mscorlib.dll", "Thinxoft.HttpLib.XFiles.dll" });
                }

                string[] asmDlls = assemblies.ToArray();
                parameters.ReferencedAssemblies.AddRange(asmDlls);



                CompilerResults results = compiler.CompileAssemblyFromSource(parameters, text);

                if (results.Errors.Count > 0)
                {
                    errorResponse.Append("<b>The Specified file contained syntax errors</b><hr>");
                    foreach (CompilerError err in results.Errors)
                    {
                        errorResponse.AppendFormat("Error({2}) L({3})[Line{1},Column{4}]: {0}<br>", err.ErrorText, err.Line, err.ErrorNumber, err.IsWarning.ToString(), err.Column);
                    }
                    return false;
                }
                File.SetAttributes(tempAssembly, FileAttributes.Hidden);  //hides the file

                return true;
            }


        }
    }
}
